﻿using POC.Configuration;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using wlog.Model;
using wlog.Shell.Storage;

namespace wlog.Shell.IO
{
    public class PrintCommand : Command
    {
        PrintOptions lastOptions = PrintOptions.Variable;
        string fileName = "";
        string location = "inline";
        int pageSize = 100;
        Queue<OutputChannel> _models = new Queue<OutputChannel>();
        TextWriter writer = null;
        public void SetModels(Queue<OutputChannel> models)
        {
            _models = models;
        }
        public override void Setup(string[] args)
        {
            try
            {
                TokenizeCommand(args);
            }
            catch (IndexOutOfRangeException exc)
            {
                Results.Add("Insufficent arguments passed.");
            }

            string options = commandObjectType.ToLower();
            if (options == PrintOptions.Top.ToString().ToLower())
            {
                lastOptions = PrintOptions.Top;
                string size = string.IsNullOrEmpty(objectName) ? "1" : objectName.Trim();
                int.TryParse(objectName, out pageSize);
            }
            else if(string.IsNullOrEmpty(options) || 
                options == PrintOptions.All.ToString().ToLower())
            {
                lastOptions = PrintOptions.All;
                // it is all... but let me see any variable matches
            }
            else
            {
                lastOptions = PrintOptions.Variable;
            }
            location = string.IsNullOrEmpty(additionalCommands[K_OPTIONS.objectlocation]) ?
                K_LOCATION.console.ToString() :
                additionalCommands[K_OPTIONS.objectlocation];
            fileName = additionalCommands[K_OPTIONS.objecturi];
            base.CreateTask(() =>
            {
                bool fileOpend = false;
                if (string.IsNullOrEmpty(fileName))
                {
                    writer = Console.Out;
                }
                else
                {
                    writer = new StreamWriter(fileName);
                    fileOpend = true;
                }
                try
                {
                    if (lastOptions == PrintOptions.Variable)
                    {
                        PrintVariable(options, writer);
                    }
                    else
                    {
                        PrintOutput(options, writer);
                    }
                }
                catch (Exception cxo)
                {
                    Console.WriteLine("Error in print, Message = " + cxo.Message);
                }
                finally
                {
                    if (fileOpend)
                    {
                        writer.Close();
                    }
                }
            });
        }
        public void PrintVariable(string key, TextWriter writer)
        {
            string value = ApplicationConfiguration.Get(key);
            writer.WriteLine("{0}={1}",key,value);
        }
        public void PrintOutput(string key, TextWriter writer)
        {
            if (_models.Any())
            {
                if (lastOptions == PrintOptions.Top)
                {
                    var reverse = _models.Take(pageSize).ToList();
                    PrintConsole(reverse, writer);
                    PrintConsole(_models.LastOrDefault(), writer);
                }
                else
                {
                    PrintConsole(_models.ToList(), writer);
                }

            }
        }
        public static void PrintConsole(OutputChannel model, TextWriter writer)
        {
            foreach (var line in model.Lines)
            {
                writer.WriteLine(line);
            }
            writer.WriteLine(Environment.NewLine);
        }
        public static void PrintConsole(List<OutputChannel> models, TextWriter writer)
        {
            foreach (var model in models)
            {
                PrintConsole(model, writer);
            }
        }

    }
}
